﻿// FluentViewModel (http://fluentviewmodel.codeplex.com/)
//
// Copyright © 2010 Kialco Group 
//
// The contents of this file are subject to the Mozilla Public
// License Version 1.1 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of
// the License at http://www.mozilla.org/MPL/
// 
// Software distributed under the License is distributed on an 
// "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
// implied. See the License for the specific language governing
// rights and limitations under the License.

using System;
using System.Collections.Generic;
using System.Linq;

namespace FluentViewModel
{
    public sealed class Configurator
    {
        private readonly IList<Type> providers;

        internal Configurator()
        {
            providers = new List<Type>();
        }

        /// <summary>
        /// Add a <see cref="IConfigurationProvider"/> into the configuration.
        /// </summary>
        /// <typeparam name="TConfigurationProvider">The type of the configuration provider.</typeparam>
        /// <returns>The current <see cref="Configurator"/> instance.</returns>
        public Configurator Add<TConfigurationProvider>()
            where TConfigurationProvider : IConfigurationProvider
        {
            providers.Add(typeof(TConfigurationProvider));
            return this;
        }

        /// <summary>
        /// Ends the configuration process by applying the <see cref="IConfigurationProvider"/> behavior to the <see cref="IServiceLocator"/>.
        /// </summary>
        /// <returns>A new <see cref="IServiceLocator"/> instance.</returns>
        public IServiceLocator End()
        {
            var serviceLocator = new ServiceLocator();
            foreach (var provider in providers
                .Select(Activator.CreateInstance)
                .OfType<IConfigurationProvider>())
                provider
                    .GetConfiguration()
                    .ApplyConfiguration(serviceLocator);
            return serviceLocator;
        }
    }
}